/******************************************************************************
* Copyright (c) 2020-2022 Xilinx, Inc. All rights reserved.
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/

/*****************************************************************************/
/**
* @file xis_translation_table_a53_64.S
*
* This file contains the initialization for the MMU table in RAM
* needed by the Cortex A53 processor (64-bit)
* This file is ImgSel local copy of the BSP file
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- ---------------------------------------------------
* 1.0  Ana   07/02/20    First release
*
* @note
*
* None.
*
******************************************************************************/
#if ! defined (__clang__)
#include "xparameters.h"

	.globl  MMUTableL0
	.globl  MMUTableL1
	.globl  MMUTableL2

	.set reserved,	0x0 					/* Fault*/
	.set Memory,	0x405 | (3 << 8) | (0x0)		/* normal writeback write allocate inner shared read write */
	.set Device,	0x409 | (1 << 53)| (1 << 54) |(0x0)	/* strongly ordered read write non executable*/
	.section .mmu_tbl0,"a"

MMUTableL0:

.set SECT, MMUTableL1		/* 0x0000_0000 -  0x7F_FFFF_FFFF */
.8byte	SECT + 0x3
.set SECT, MMUTableL1+0x1000	/* 0x80_0000_0000 - 0xFF_FFFF_FFFF */
.8byte	SECT + 0x3

	.section .mmu_tbl1,"a"

MMUTableL1:

.set SECT, MMUTableL2		/* 0x0000_0000 - 0x3FFF_FFFF */
.8byte	SECT + 0x3		/* 1GB DDR */

.rept	0x3			/* 0x4000_0000 - 0xFFFF_FFFF */
.set SECT, SECT + 0x1000	/*1GB DDR, 1GB PL, 2GB other devices n memory */
.8byte	SECT + 0x3
.endr

.set SECT,0x100000000
.rept	0xC			/* 0x0001_0000_0000 - 0x0003_FFFF_FFFF */
.8byte	SECT + reserved		/* 12GB Reserved */
.set SECT, SECT + 0x40000000
.endr

.rept	0x10			/* 0x0004_0000_0000 - 0x0007_FFFF_FFFF */
.8byte	SECT + Device		/* 8GB PL, 8GB PCIe */
.set SECT, SECT + 0x40000000
.endr


#ifdef XPAR_PSU_DDR_1_S_AXI_BASEADDR
.set DDR_1_START, XPAR_PSU_DDR_1_S_AXI_BASEADDR
.set DDR_1_END, XPAR_PSU_DDR_1_S_AXI_HIGHADDR
.set DDR_1_SIZE, (DDR_1_END - DDR_1_START)+1
.if DDR_1_SIZE > 0x800000000
/* If DDR size is larger than 32GB, truncate to 32GB */
.set DDR_1_REG, 0x20
.else
.set DDR_1_REG, DDR_1_SIZE/0x40000000
.endif
#else
.set DDR_1_REG, 0
#warning "There's no DDR_1 in the HW design. MMU translation table marks 32 GB DDR address space as undefined"
#endif

.set UNDEF_1_REG, 0x20 - DDR_1_REG

.rept	DDR_1_REG			/* DDR based on size in hdf*/
.8byte	SECT + reserved		/* this region marked as Memory after DDR init */
.set	SECT, SECT+0x40000000
.endr

.rept	UNDEF_1_REG		/* reserved for region where ddr is absent */
.8byte	SECT + reserved
.set SECT, SECT + 0x40000000
.endr

.rept	0x1C0			/* 0x0010_0000_0000 - 0x007F_FFFF_FFFF */
.8byte	SECT + Device		/* 448 GB PL */
.set SECT, SECT + 0x40000000
.endr


.rept	0x100			/* 0x0080_0000_0000 - 0x00BF_FFFF_FFFF */
.8byte	SECT + Device		/* 256GB PCIe */
.set SECT, SECT + 0x40000000
.endr


.rept	0x100			/* 0x00C0_0000_0000 - 0x00FF_FFFF_FFFF */
.8byte	SECT + reserved		/* 256GB reserved */
.set SECT, SECT + 0x40000000
.endr


.section .mmu_tbl2,"a"

MMUTableL2:

.set SECT, 0

#ifdef XPAR_PSU_DDR_0_S_AXI_BASEADDR
.set DDR_0_START, XPAR_PSU_DDR_0_S_AXI_BASEADDR
.set DDR_0_END, XPAR_PSU_DDR_0_S_AXI_HIGHADDR
.set DDR_0_SIZE, (DDR_0_END - DDR_0_START)+1
.if DDR_0_SIZE > 0x80000000
/* If DDR size is larger than 2GB, truncate to 2GB */
.set DDR_0_REG, 0x400
.else
.set DDR_0_REG, DDR_0_SIZE/0x200000
.endif
#else
.set DDR_0_REG, 0
#warning "There's no DDR_0 in the HW design. MMU translation table marks 2 GB DDR address space as undefined"
#endif

.set UNDEF_0_REG, 0x400 - DDR_0_REG

.rept	DDR_0_REG			/* DDR based on size in hdf*/
.8byte	SECT + reserved		/* this region marked as Memory after DDR init */
.set	SECT, SECT+0x200000
.endr

.rept	UNDEF_0_REG		/* reserved for region where ddr is absent */
.8byte	SECT + reserved
.set	SECT, SECT+0x200000
.endr

.rept	0x0200			/* 0x8000_0000 - 0xBFFF_FFFF */
.8byte	SECT + Device		/* 1GB lower PL */
.set	SECT, SECT+0x200000
.endr

.rept	0x0100			/* 0xC000_0000 - 0xDFFF_FFFF */
.8byte	SECT + Device		/* 512MB QSPI */
.set	SECT, SECT+0x200000
.endr

.rept	0x080			/* 0xE000_0000 - 0xEFFF_FFFF */
.8byte	SECT + Device		/* 256MB lower PCIe */
.set	SECT, SECT+0x200000
.endr

.rept	0x040			/* 0xF000_0000 - 0xF7FF_FFFF */
.8byte	SECT + reserved		/* 128MB Reserved */
.set	SECT, SECT+0x200000
.endr

.rept	0x8			/* 0xF800_0000 - 0xF8FF_FFFF */
.8byte	SECT + Device		/* 16MB coresight */
.set	SECT, SECT+0x200000
.endr

/* 1MB RPU LLP is marked for 2MB region as the minimum block size in
   translation table is 2MB and adjacent 63MB reserved region is
   converted to 62MB */

.rept	0x1			/* 0xF900_0000 - 0xF91F_FFFF */
.8byte	SECT + Device		/* 2MB RPU low latency port */
.set	SECT, SECT+0x200000
.endr

.rept	0x1F			/* 0xF920_0000 - 0xFCFF_FFFF */
.8byte	SECT + reserved		/* 62MB Reserved */
.set	SECT, SECT+0x200000
.endr

.rept	0x8			/* 0xFD00_0000 - 0xFDFF_FFFF */
.8byte	SECT + Device		/* 16MB FPS */
.set	SECT, SECT+0x200000
.endr

.rept	0xE			/* 0xFE00_0000 -  0xFFBF_FFFF */
.8byte	SECT + Device		/* 28MB LPS */
.set	SECT, SECT+0x200000
.endr

				/* 0xFFC0_0000 - 0xFFDF_FFFF */
.8byte	SECT + Device 		/*2MB PMU/CSU */

.set	SECT, SECT+0x200000	/* 0xFFE0_0000 - 0xFFFF_FFFF*/
.8byte  SECT + Memory		/*2MB OCM/TCM*/

.end

#else

#include "xparameters.h"

	EXPORT MMUTableL0
	EXPORT MMUTableL1
	EXPORT MMUTableL2

   GBLA abscnt
   GBLA count
   GBLA sect

; Fault
Reserved EQU 0

Memory EQU 0x405:OR:(3:SHL:8):OR:0x0 ; Normal writeback write allocate inner shared read write

Device EQU 0x409:OR:(1:SHL:53):OR:(1:SHL:54):OR:0x0 ; Strongly ordered read write non executable

 AREA |.mmu_tbl0|, CODE, ALIGN=12

MMUTableL0

   DCQU MMUTableL1+0x3 ; 0x0000_0000 - 0x7F_FFFF_FFFF
   DCQU MMUTableL1+0x1000+0x3 ; 0x80_0000_0000 - 0xFF_FFFF_FFFF

 AREA |.mmu_tbl1|, CODE, ALIGN=12

MMUTableL1

;
; 0x4000_0000 - 0xFFFF_FFFF
; 1GB DDR, 1GB PL, 2GB other devices n memory
;
count SETA 0
   WHILE count<0x4
   DCQU MMUTableL2+count*0x1000+0x3
count SETA count+1
   WEND

Fixlocl1 EQU 0x100000000
abscnt SETA 0

;
; 0x0001_0000_0000 - 0x0003_FFFF_FFFF
; 12GB Reserved
;
count SETA 0
   WHILE count<0xc
   DCQU Fixlocl1+abscnt*0x40000000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0x0004_0000_0000 - 0x0007_FFFF_FFFF
; 8GB PL, 8GB PCIe
;
count SETA 0
   WHILE count<0x10
   DCQU Fixlocl1+abscnt*0x40000000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND


DDR_1_START EQU 0x800000000
DDR_1_END EQU 0x87FFFFFFF
DDR_1_SIZE EQU (DDR_1_END - DDR_1_START + 1)



DDR_1_REG EQU DDR_1_SIZE / 0x40000000





UNDEF_1_REG EQU (0x20 - DDR_1_REG)

; DDR based on size in hdf
count SETA 0
   WHILE count<DDR_1_REG
   DCQU Fixlocl1+abscnt*0x40000000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

; Reserved for region where ddr is absent
count SETA 0
   WHILE count<UNDEF_1_REG
   DCQU Fixlocl1+abscnt*0x40000000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0x0010_0000_0000 - 0x007F_FFFF_FFFF
; 448 GB PL
;
count SETA 0
   WHILE count<0x1C0
   DCQU Fixlocl1 + abscnt * 0x40000000 + Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0x0080_0000_0000 - 0x00BF_FFFF_FFFF
; 256GB PCIe
;
count SETA 0
   WHILE count<0x100
   DCQU Fixlocl1+abscnt*0x40000000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0x00C0_0000_0000 - 0x00FF_FFFF_FFFF
; 256GB Reserved
;
count SETA 0
   WHILE count<0x100
   DCQU Fixlocl1+abscnt*0x40000000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

 AREA |.mmu_tbl2|, CODE, ALIGN=12

MMUTableL2

abscnt SETA 0


DDR_0_START EQU 0x00000000
DDR_0_END EQU 0x7FFFFFFF
DDR_0_SIZE EQU (DDR_0_END - DDR_0_START + 1)



DDR_0_REG EQU DDR_0_SIZE / 0x200000





UNDEF_0_REG EQU (0x400 - DDR_0_REG)

; DDR based on size in hdf
count SETA 0
   WHILE count<DDR_0_REG
   DCQU abscnt*0x200000+Reserved        ; this region marked as Memory after DDR init
count SETA count+1
abscnt SETA abscnt+1
   WEND

; Reserved for region where ddr is absent
count SETA 0
   WHILE count<UNDEF_0_REG
   DCQU abscnt*0x200000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0x8000_0000 - 0xBFFF_FFFF
; 1GB lower PL
;
count SETA 0
   WHILE count<0x0200
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xC000_0000 - 0xDFFF_FFFF
; 512MB QSPI
;
count SETA 0
   WHILE count<0x0100
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xE000_0000 - 0xEFFF_FFFF
; 256MB lower PCIe
;
count SETA 0
   WHILE count<0x080
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND
;
; 0xF000_0000 - 0xF7FF_FFFF
; 128MB Reserved
;
count SETA 0
   WHILE count<0x040
   DCQU abscnt*0x200000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xF800_0000 - 0xF8FF_FFFF
; 16MB Coresight
;
count SETA 0
   WHILE count<0x8
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 1MB RPU LLP is marked for 2MB region as the minimum block size in translation
; table is 2MB and adjacent 63MB reserved region is converted to 62MB
;

;
; 0xF900_0000 - 0xF91F_FFFF
; 2MB RPU low latency port
;
count SETA 0
   WHILE count<0x1
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xF920_0000 - 0xFCFF_FFFF
; 62MB Reserved
;
count SETA 0
   WHILE count<0x1f
   DCQU abscnt*0x200000+Reserved
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xFD00_0000 - 0xFDFF_FFFF
; 16MB FPS
;
count SETA 0
   WHILE count<0x8
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xFE00_0000 - 0xFFBF_FFFF
; 28MB LPS
;
count SETA 0
   WHILE count<0xE
   DCQU abscnt*0x200000+Device
count SETA count+1
abscnt SETA abscnt+1
   WEND

;
; 0xFFC0_0000 - 0xFFDF_FFFF
; 2MB PMU/CSU
;
   DCQU abscnt*0x200000+Device

abscnt SETA abscnt+1

;
; 0xFFE0_0000 - 0xFFFF_FFFF
; 2MB OCM/TCM
;
   DCQU abscnt*0x200000+Memory

    END

;
; @} End of "addtogroup a53_64_boot_code"
;
#endif
